package com.xzy.mybatis.cipher.support.strategy.crypto;

import com.xzy.mybatis.cipher.support.enums.CryptoStrategyEnum;
import com.xzy.mybatis.cipher.support.exceptions.UnsupportedCryptoStrategyException;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xzy.xiao
 * @since 2025/2/21  21:03
 */
@Slf4j
public class CryptoStrategyFactory {

    private static final Map<String, Class<? extends CryptoStrategy>> CRYPTO_STRATEGY_MAP = new ConcurrentHashMap<>();

    // System crypto strategy
    static {
        registerStrategy(CryptoStrategyEnum.AES.getCode(), AesCryptoStrategy.class);
        registerStrategy(CryptoStrategyEnum.DES.getCode(), DesCryptoStrategy.class);
        registerStrategy(CryptoStrategyEnum.MD5.getCode(), Md5CryptoStrategy.class);
    }

    public static void registerStrategy(String name, Class<? extends CryptoStrategy> clazz) {
        log.debug("Register crypto strategy: {}", name);
        CRYPTO_STRATEGY_MAP.put(name, clazz);
    }

    public static CryptoStrategy getStrategy(String name, String key) throws Exception {
        Class<? extends CryptoStrategy> clazz = CRYPTO_STRATEGY_MAP.get(name);
        if (clazz == null) {
            throw new UnsupportedCryptoStrategyException("Unsupported crypto strategy: " + name);
        }

        Constructor<? extends CryptoStrategy> constructor = clazz.getConstructor(String.class);
        return constructor.newInstance(key);
    }
}
